home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / dos / runback4.1 < prev    next >
Internet Message Format  |  1989-05-18  |  24KB

  1. Path: xanth!ames!amdahl!oliveb!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i138:  runback - run commands in the background v4
  5. Message-ID: <105547@sun.Eng.Sun.COM>
  6. Date: 17 May 89 14:59:08 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 757
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: kim@uts.amdahl.com (Kim E. DeVaughn)
  12. Posting-number: Volume 89, Issue 138
  13. Archive-name: dos/runback4.1
  14.  
  15. RunBack now uses the NULL: device (by Gunnar Nordmark).  This is a
  16. "real" device, so it solves the problems with previous versions of
  17. RunBack that used the Nil: "fake" device which caused crashes.
  18.  
  19. [null: not included here, as it has already been posted.  The handler
  20. is in the runback.zoo file in comp.binaries.amiga however.  ..bob]
  21.  
  22. # This is a shell archive.
  23. # Remove anything above and including the cut line.
  24. # Then run the rest of the file through 'sh'.
  25. # Unpacked files will be owned by you and have default permissions.
  26. #----cut here-----cut here-----cut here-----cut here----#
  27. #!/bin/sh
  28. # shar: SHell ARchive
  29. # Run the following text through 'sh' to create:
  30. #    Makefile
  31. #    Mountlist
  32. #    README
  33. #    README.barrett
  34. #    README.peck
  35. #    amigaline-D1
  36. #    aztec.c
  37. #    path.c
  38. #    runback.c
  39. # This is archive 1 of a 1-part kit.
  40. # This archive created: Wed May 17 19:53:12 1989
  41. echo "extracting Makefile"
  42. sed 's/^X//' << \SHAR_EOF > Makefile
  43. XCFLAGS=+L
  44. XOBJ=runback.o path.o aztec.o
  45. XPROG=RunBack
  46. X
  47. Xall:    $(OBJ)
  48. X    ln $(OBJ) -o $(PROG) -lc32
  49. X
  50. Xclean:
  51. X    delete \#?.o $(PROG)
  52. SHAR_EOF
  53. echo "extracting Mountlist"
  54. sed 's/^X//' << \SHAR_EOF > Mountlist
  55. X
  56. X/*  
  57. X    Installs null-handler V 0.0 (C) Gunnar Nordmark
  58. X*/
  59. X
  60. Xnull:      Handler = L:null-handler
  61. X           Stacksize = 500
  62. X           Priority = 5
  63. X       GlobVec = 1
  64. X#
  65. SHAR_EOF
  66. echo "extracting README"
  67. sed 's/^X//' << \SHAR_EOF > README
  68. XRunBack:        Run a program in the background.
  69. X        ***     Now searches your command search path.  ***
  70. X                A revision of Daniel Barrett's version of
  71. X                Rob Peck's "RunBack" program. (Got That ?)
  72. X
  73. XAuthor:         Tim Maffett
  74. X                Molecular Design Ltd.
  75. X                2132 Farallon Dr.
  76. X                San Leandro, CA 94577
  77. X
  78. X
  79. XNote:           All previous versions of RunBack have been placed in the
  80. X                Public Domain.  So is all the code I've added.
  81. X
  82. X                See README.barrett and README.peck for info on
  83. X                previous versions.
  84. X
  85. X
  86. XINTRODUCTION
  87. X------------
  88. X        This version of RunBack has been changed to use the NULL: device
  89. Xsupplied in this ZOO file. (NULL: device by Gunnar Nordmark).  This
  90. Xis a "real" device, so it solve problems with previous versions of RunBack
  91. Xwhich used the Nil: "fake" device which caused Crashes....
  92. X
  93. XNOTE:   Gunnar's NULL: device is supplied in this archive. (in the
  94. X      null directory if you used zoo x// RUNBACK4.ZOO to unzoo)
  95. X
  96. X        See the "null.doc" file and Matt Dillon's "amigaline-d1" article for
  97. Xmore info.
  98. X
  99. X1)      The "null-handler" handler needs to be placed in you l: directory
  100. X and the MountList suplied in nul.zoo must be appended to Your MountList.
  101. X (SEE "null.doc: for details).
  102. X2)      RunBack will take care of mounting Null: for you, so there is no
  103. X need for you to explicitly "mount null:" before using RunBack.
  104. X3)      RunBack still contains Daniel Barrett's modifications so your
  105. X command search path will be searched; ie. you do not have to supply full
  106. X path names to the command you want to RunBack.
  107. X
  108. X
  109. XSO WHAT ?
  110. X---------
  111. X        Commands which would previously cause RunBack (RunBack3) to
  112. Xguru should now work (if the guru was cause by the program trying to
  113. Xcommunicate with the Nil: "fake" device).  Using Gunnar's NULL: device,
  114. Xa true "bit bucket", provides more functionality.
  115. X
  116. X
  117. XSee README.barrett and README.peck for more info on RunBack and it's history.
  118. XNote change all references to "Nil:" to "Null:"
  119. X
  120. XSee null.doc for more info on NULL:
  121. X
  122. SHAR_EOF
  123. echo "extracting README.barrett"
  124. sed 's/^X//' << \SHAR_EOF > README.barrett
  125. XRunBack:    Run a program in the background.
  126. X    ***    Now searches your command search path.    ***
  127. X        A revision of Rob Peck's "RunBack" program and
  128. X         Carolyn Scheppner's "Which" program.
  129. X
  130. XAuthor:        Daniel Barrett
  131. X        Department of Computer Science
  132. X        The Johns Hopkins University
  133. X        Baltimore, MD  21218
  134. X
  135. X        barrett@cs.jhu.edu
  136. X        ins_adjb@jhunix.UUCP
  137. X
  138. XNote:        Both the original RunBackground and Which are in 
  139. X        the Public Domain.  So is all my code that I added.
  140. X        Use it however you please.
  141. X
  142. XINTRODUCTION
  143. X------------
  144. X    This is my altered version of Rob Peck's fine program, RunBack.
  145. XRunBack, similar to Run, allows you to startup a CLI program and let
  146. Xit run in the background.  Unlike Run, however, RunBack then allows 
  147. Xthe original CLI to be closed.  Run would hang the CLI if you did this.
  148. XSee the file README.peck for Rob Peck's original documentation.
  149. X
  150. X    Also unlike Run, the old RunBack did not search your command search
  151. Xpath; you always had to specify the complete pathname of your command.
  152. XMy new version eliminates this hassle -- it searches your path.
  153. X
  154. X    The path-searching code is largely taken from Carolyn Scheppner's
  155. X"Which" program.  Thanks, Carolyn!!
  156. X
  157. XA PROBLEM I HAD TO OVERCOME
  158. X---------------------------
  159. X
  160. X    The original RunBack program I obtained was a binary version, 
  161. Xcompiled with the Lattice C compiler.  I use the Manx (Aztec) compiler, 
  162. Xversion 3.6a.  When I compiled Rob's original program with Manx, something
  163. Xdid not work anymore... quoted arguments on the command line.  The Manx 
  164. Xversion completely drops the quotes!
  165. X
  166. XThe way RunBack works is that it translates:
  167. X
  168. X    RunBack myProgram arg1 arg2
  169. X
  170. Xinto:
  171. X
  172. X    Run >NIL: <NIL: myProgram >NIL: <NIL: arg1 arg2
  173. X
  174. XSo a Lattice RunBack would translate from:
  175. X
  176. X    RunBack c:emacs "my file"
  177. X
  178. Xinto:
  179. X
  180. X    Run >NIL: <NIL: c:emacs >NIL: <NIL: "my file"
  181. X
  182. XHOWEVER, Manx-compiled RunBack translates it into:
  183. X
  184. X    Run >NIL: <NIL: c:emacs >NIL: <NIL: my file
  185. X
  186. Xwhich is clearly WRONG.
  187. X
  188. X    What did I do about it?  I added a few lines of #ifdef AZTEC_C
  189. Xcode to the runback.c program, plus the file aztec.c.  I am effectively
  190. Xreplacing quotes around quoted arguments.  My algorithm is this:  if
  191. Xan argument has a blank space in it, then it must have been quoted, so
  192. Xput quotes around it.
  193. X    If you don't like this algorithm, the source code is included 
  194. Xand you can change it any way you like.
  195. X    Since I don't have the Lattice compiler, I cannot be sure that
  196. Xmy changes will work under Lattice.  That is why I made all my changes
  197. X#ifdef AZTEC_C, a constant that is automatically defined by Manx C
  198. Xafter version 3.4a.
  199. X
  200. X    Enjoy the program!
  201. SHAR_EOF
  202. echo "extracting README.peck"
  203. sed 's/^X//' << \SHAR_EOF > README.peck
  204. X/* 
  205. X
  206. X--------------
  207. Xrunbackground.c  
  208. X---------------
  209. X
  210. XSUMMARY:  A Workbench Disk can be used to autostart an application
  211. X      through the use of the startup script and close the startup CLI.
  212. X
  213. X
  214. XUsers have commented that it is not possible to start a process going 
  215. Xfrom the startup script and then cause the initial CLI to go away.   
  216. XHere is the solution to that problem, named appropriately:
  217. X
  218. X    RUNBACKGROUND
  219. X
  220. Xwhich starts and runs a background task.  This does indeed allow you to
  221. Xcreate a startup script that will set up your workbench running any
  222. Xprograms you might wish, removing the initial CLI in the process.
  223. X
  224. XYour s/startup-sequence can contain lines such as the following:
  225. X
  226. X    RUNBACKGROUND -3 clock
  227. X    RUNBACKGROUND utilities/calculator
  228. X    RUNBACKGROUND -5 utilities/notepad
  229. X
  230. Xwhere RUNBACKGROUND is the command and the second parameter is the filename
  231. Xwhich may be preceded by a flag-variable that specifies an optional delay 
  232. Xtime.  The delay can be from 0 to 9, for the number of seconds that 
  233. Xthe startup script should sleep while allowing the background task to 
  234. Xload and start.  I've put that in to minimize thrashing of the disk as it
  235. Xtries to load several projects at once.
  236. X
  237. X
  238. XLIMITATIONS:
  239. X
  240. X    The program that you run cannot require any input from an interactive
  241. X    CLI that starts it.    Additionally, you cannot specify any file 
  242. X    redirection in the command line since this program provides the
  243. X    redirection for you already.  If you need to use redirection for
  244. X    your command, you can modify the source code where shown, thus
  245. X    allowing the redirection to become one of the parameters passed
  246. X    through to your program.
  247. X
  248. X    RUNBACKGROUND does pass your command line parameters to the program
  249. X    you wish to start, but limits the total length of your command
  250. X    string to 227 (255 minus the 28 characters for "RUN >NIL: <NIL: " 
  251. X    preceding your own file pathname and ">NIL: < NIL: " following it.)
  252. X
  253. X
  254. XLINKING INFORMATION:
  255. X
  256. X    (Amiga/Lattice C)    use -v option for pass 2   (lc2 -v filename.q)
  257. X            to disable stack checking code installation.
  258. X            (stack checking code sometimes is incorrect).
  259. X
  260. X    FROM lib:Astartup.obj runbackground.o
  261. X    TO runbackground
  262. X    LIBRARY lib:amiga.lib, lib:lc.lib
  263. X
  264. X    ****************************  NOTE:  ********************************
  265. X    If you use Lstartup.obj, it won't let the startup CLI go away. This is
  266. X    because the source code for Lstartup.asm either opens its own window 
  267. X    or uses an existing CLI window (Open("*",....)), so that it has some 
  268. X    guaranteed place to put the output.   Astartup.obj does not do this.
  269. X    *********************************************************************
  270. X
  271. XHope this helps.
  272. X
  273. X
  274. Xrobp.
  275. X*/
  276. X
  277. SHAR_EOF
  278. echo "extracting amigaline-D1"
  279. sed 's/^X//' << \SHAR_EOF > amigaline-D1
  280. X    AMIGALINE #D1,    Matthew Dillon
  281. X
  282. X    Disconnecting a program such that you can EndCLI and also allow the
  283. X    program to call Execute().
  284. X
  285. XProblem:
  286. X
  287. X    You want to disconnect a program such that when you RUN <nil: >nil:
  288. X    (using the new 1.3 RUN) you can then EndCLI the cli.
  289. X
  290. X    This program wants to be able to use Execute() to run other programs. 
  291. X    The problem is that Execute() requires a valid pr_ConsoleTask (console)
  292. X    or it will freeze.
  293. X
  294. XSolution: General
  295. X
  296. X    Run <nil: >nil: mycprogram
  297. X
  298. X    If using the main() entry point, you can fclose(stderr) to remove
  299. X    the reference to "*".  If using the _main() entry point, stdio is
  300. X    not setup and thus you do not need to do this (in fact, you can't
  301. X    use stdio at all without crashing the computer).
  302. X
  303. X    note: being able to fclose(stderr) from the main() entry point 
  304. X    works with Aztec C.  I don't know about Lattice.  Aztec always
  305. X    does an Open("*", 1006) to setup stderr and this reference must
  306. X    be removed.
  307. X
  308. X                    --
  309. X
  310. X    At this point, you can EndCLI and the cli window goes away.  However,
  311. X    the 'mycprogram' cannot call Execute() or otherwise run other 
  312. X    external programs for two reasons:
  313. X
  314. X        (1) pr_ConsoleTask is still non-NULL and points to the now
  315. X            defunct window (i.e. you will cause a task-held requester)
  316. X
  317. X        (2) you cannot set pr_ConsoleTask to NULL... Execute() does
  318. X            not accept it and freezes up.
  319. X
  320. X                    --
  321. X
  322. X    So, you must set pr_ConsoleTask to some other valid device.  Guess
  323. X    what?  Any device will do except NIL: which isn't a real device.  For
  324. X    example, RAM: :
  325. X
  326. X        extern APTR DeviceProc();
  327. X        proc->pr_ConsoleTask = DeviceProc("ram:");
  328. X
  329. X        (assuming RAM: exists)
  330. X
  331. X    What does this do?  Any program which tries to open the console will
  332. X    actually open the file "RAM:*", as in Open("RAM:*", 1006).  
  333. X    Unfortunetly, there is no way to place "*" in anything but the 
  334. X    root directory of the device.  This is essentially a garbage file.
  335. X
  336. X    But the ultimate goal is achieved ... you can kill the CLI window
  337. X    and still arbitrarily run programs from the detached program with
  338. X    impunity.
  339. X
  340. X    The only possible problem which I have yet to test is when several
  341. X    programs try to access RAM:* as their console at the same time.  
  342. X    Since the file is openned 1006, other programs trying to Open() it
  343. X    will fail while the first programs is still running.  What happens?
  344. X
  345. X                            -Matt
  346. SHAR_EOF
  347. echo "extracting aztec.c"
  348. sed 's/^X//' << \SHAR_EOF > aztec.c
  349. X/* HasASpace(s):    Return 1 if there is a space in string s.
  350. X *            Return 0 otherwise.
  351. X*/
  352. X
  353. XHasASpace(s)
  354. Xchar *s;
  355. X{
  356. X    char *temp=s;
  357. X    while (*temp) {
  358. X        if (*(temp++) == ' ')
  359. X            return(1);
  360. X    }
  361. X    return(0);
  362. X}
  363. SHAR_EOF
  364. echo "extracting path.c"
  365. sed 's/^X//' << \SHAR_EOF > path.c
  366. X/* This code is taken largely from Carolyn Scheppner's "which.c" program
  367. X * from 11/87.  There were no copyright notices in the original file,
  368. X * so to the best of my knowledge it is in the Public Domain.
  369. X*/
  370. X
  371. X#include <exec/types.h>
  372. X#include <exec/memory.h>
  373. X#include <libraries/dos.h>
  374. X#include <libraries/dosextens.h>
  375. X
  376. X#define SBUFSZ 256
  377. X#define CBUFSZ 80
  378. X
  379. Xextern BOOL getPath();
  380. Xextern struct Task *FindTask();        /* To scare away warning msgs */
  381. Xextern VOID *AllocMem();
  382. X    
  383. Xstruct Path
  384. X   {
  385. X   BPTR  path_Next;
  386. X   LONG  path_Lock;
  387. X   };
  388. X
  389. Xchar *FindIt(command)
  390. Xchar *command;
  391. X{
  392. X   struct Process *proc;
  393. X   struct CommandLineInterface *cli;
  394. X   struct Path *path;
  395. X   struct FileInfoBlock *fib;
  396. X   APTR oldWindowPtr;
  397. X   LONG lock, startcd;
  398. X   BOOL Found, InitialCD, FullPath;
  399. X   int  i;
  400. X   char sbuf[SBUFSZ], cbuf[CBUFSZ];
  401. X
  402. X   /* Fail if not CLI process */
  403. X   proc = (struct Process *)FindTask(NULL);
  404. X   cli = (struct CommandLineInterface *)(proc->pr_CLI << 2);
  405. X   if(!cli)  exit(RETURN_ERROR);
  406. X
  407. X   /* Allocate a FileInfoBlock - must be longword aligned */
  408. X   if(!(fib=(struct FileInfoBlock *)
  409. X     AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)))
  410. X      printf("Not enough memory\n"), exit(RETURN_FAIL);
  411. X
  412. X   /* Save old WindowPtr, and disable volume requesters */
  413. X   oldWindowPtr = proc->pr_WindowPtr;
  414. X   proc->pr_WindowPtr = (APTR)-1L;
  415. X
  416. X   /* Were we given full path in command name ? */
  417. X   for(FullPath = FALSE, i=0; i<strlen(command); i++)
  418. X     {
  419. X     if(command[i] == ':')
  420. X        {
  421. X        FullPath = TRUE;
  422. X        break;
  423. X        }
  424. X     }
  425. X
  426. X   /* Check current directory */
  427. X   if(Found = getPath(command,fib,sbuf))
  428. X      {
  429. X      if((!FullPath)&&(command[0]))  strcpy(sbuf,command);
  430. X      }
  431. X
  432. X   /* Check paths */
  433. X   if((!Found)&&(!FullPath))
  434. X      {
  435. X      InitialCD = TRUE;
  436. X      /* Follow the BPTR path list */
  437. X      for(path = (struct Path *) BADDR(cli->cli_CommandDir);
  438. X          (path) && (!Found);
  439. X            path = (struct Path *) BADDR(path->path_Next))
  440. X         {
  441. X         /* CD to each path */
  442. X         lock = CurrentDir(path->path_Lock);
  443. X         if(InitialCD)  startcd = lock, InitialCD = FALSE;
  444. X
  445. X         /* See if command is there */
  446. X         Found = getPath(command,fib,sbuf);
  447. X         }
  448. X      /* If we CD'd anywhere, restore initial CD */
  449. X      if(! InitialCD)  CurrentDir(startcd);
  450. X      }
  451. X
  452. X   /* Check C: */
  453. X   if((!Found)&&(!FullPath))
  454. X      {
  455. X      strcpy(cbuf,"C:");
  456. X      strcpy(&cbuf[2],command);
  457. X      if(Found = getPath(cbuf,fib,sbuf))  strcpy(sbuf,cbuf);
  458. X      }
  459. X
  460. X   /* Re-enable volume requesters */
  461. X   proc->pr_WindowPtr = oldWindowPtr;
  462. X
  463. X   /* Free fib */
  464. X   if (fib)
  465. X    FreeMem(fib, sizeof(struct FileInfoBlock));
  466. X
  467. X   if(Found)
  468. X    return(sbuf);
  469. X   else
  470. X    return(NULL);
  471. X}
  472. X
  473. X
  474. XBOOL
  475. XgetPath(command,fib,buf)
  476. Xchar *command;
  477. Xstruct FileInfoBlock *fib;
  478. Xchar *buf;
  479. X   {
  480. X   LONG lock;
  481. X   BOOL Success = FALSE;
  482. X
  483. X   if(lock = Lock(command,ACCESS_READ))
  484. X      {
  485. X      if(Examine(lock,fib))
  486. X         {
  487. X         Success = TRUE;
  488. X         buildPath(lock,fib,buf);
  489. X         }
  490. X      UnLock(lock);
  491. X      }
  492. X   return(Success);
  493. X   }
  494. X
  495. X
  496. XbuildPath(inlock,fib,buf)
  497. XLONG inlock;
  498. Xstruct FileInfoBlock *fib;
  499. Xchar *buf;
  500. X   {
  501. X   int i;
  502. X   LONG lock,oldlock;
  503. X   BOOL MyOldLock = FALSE;
  504. X
  505. X   buf[0] = NULL;
  506. X   lock = inlock;
  507. X
  508. X   while(lock)
  509. X      {
  510. X      if(Examine(lock,fib))
  511. X         {
  512. X         if(fib->fib_FileName[0] > ' ')
  513. X            {
  514. X            if(buf[0]) insert(buf,"/");
  515. X            insert(buf,fib->fib_FileName);
  516. X            }
  517. X         }
  518. X      oldlock = lock;
  519. X      lock = ParentDir(lock);
  520. X      if(MyOldLock)  UnLock(oldlock);
  521. X      else           MyOldLock = TRUE;
  522. X      }
  523. X
  524. X   if(fib->fib_FileName[0] > ' ')
  525. X      {
  526. X      for(i=0; i<(strlen(buf)); i++)
  527. X         {
  528. X         if(buf[i] == '/')
  529. X            {
  530. X            buf[i] = ':';
  531. X            break;
  532. X            }
  533. X         }
  534. X      }
  535. X   else  insert(buf,"RAM:");
  536. X
  537. X   return(strlen(buf));
  538. X   }
  539. X
  540. Xinsert(buf,s)
  541. Xchar *buf,*s;
  542. X   {
  543. X   char tmp[SBUFSZ];
  544. X
  545. X   strcpy(tmp,buf);
  546. X   strcpy(buf,s);
  547. X   strcpy(&buf[strlen(s)],tmp);
  548. X   }
  549. X
  550. SHAR_EOF
  551. echo "extracting runback.c"
  552. sed 's/^X//' << \SHAR_EOF > runback.c
  553. X/* runbackground.c */
  554. X/* Author:  Rob Peck.  5/9/86 */
  555. X
  556. X/* Modified 5/21/88 by Dan Barrett to include PATH searching; added
  557. X * the functions FullPathOf() and FindIt(), largely taken from C.
  558. X * Scheppner's "which.c" program.
  559. X *
  560. X * Also, a few "#ifdef AZTEC_C" lines had to be added.  It seems that
  561. X * Aztec C parses the command line differently from the way Lattice
  562. X * does with respect to arguments in quotes.  When I compiled this
  563. X * program with Aztec, all the quotes in quoted arguments were
  564. X * disappearing.  I re-insert them around any argument that has a
  565. X * space character (' ') in it.
  566. X*/
  567. X/* Modified 5/12/89 by Tim Maffett to use Gunnar Nordmark's NULL:
  568. X * device.  RunBack also Mounts the NULL: device before using.
  569. X*/
  570. X
  571. X/*#define DEBUG*/       /* Uncomment this line for debugging. */
  572. X
  573. X#define EQUAL(a,b)      !strcmp(a,b)
  574. X
  575. X#include "exec/types.h"
  576. X#include "exec/memory.h"
  577. X#include "libraries/dosextens.h"
  578. X
  579. Xextern struct FileHandle *Open();
  580. Xextern struct FileLock *Lock();
  581. Xextern VOID *AllocMem();
  582. X
  583. Xmain(argc, argv)
  584. Xint argc;
  585. Xchar *argv[];
  586. X{
  587. X    LONG success, delaywillbe;
  588. X    UBYTE commandstring[255];
  589. X    char *test, *filename;
  590. X    LONG fromparm;
  591. X    LONG *port;
  592. X    struct FileInfoBlock *fib;
  593. X    struct FileHandle *nilfh;   /* NOTE: will hang around until next reset */
  594. X    struct FileLock *lock, *FullPathOf();
  595. X#ifdef AZTEC_C
  596. X    int hasSpace=0;             /* Does an string have a space in it. */
  597. X#endif
  598. X
  599. X    fib = NULL;                 /* No file info block so far. */
  600. X    delaywillbe = 1;
  601. X
  602. X    if(argc < 2 || EQUAL(argv[1],"?")) {
  603. Xusage:
  604. X        printf("Usage: RUNBACKGROUND [ -<loaddelay>] <name> [<parm(s)>]\n");
  605. X        printf("          where optional loaddelay is 0-9,\n");
  606. X        printf("          specified in seconds for the CLI\n");
  607. X        printf("          to sleep, waiting for task to load\n");
  608. X        printf("          (minimizes inter-task disk-thrashing)\n");
  609. X        if(fib)
  610. X                FreeMem(fib, sizeof(struct FileInfoBlock));
  611. X        exit(0);
  612. X    }
  613. X
  614. X    /* See if there is a delay parameter present */
  615. X
  616. X    test = argv[1];
  617. X
  618. X    if(*test++ == '-') {
  619. X        filename = argv[2];     /* argv[1] is delay so argv[2] is file  */
  620. X        fromparm = 3;           /* Copy parms from 3 to end             */
  621. X
  622. X        if(*test >= '0' && *test <= '9')
  623. X            delaywillbe = 1 + (50 * (*test - '0'));
  624. X
  625. X        if (argc < 3)
  626. X                goto usage; /* Only a delay, and no filename!! */
  627. X
  628. X        argc--;         /* one less parm to copy */
  629. X    }
  630. X    else {
  631. X        filename = argv[1];
  632. X        fromparm = 2;           /* Copy parms from 2 to end             */
  633. X    }
  634. X
  635. X    /* Now see if the file exists!  If not, it can crash the background
  636. X     * CLI and take the system along with it.
  637. X     */
  638. X
  639. X    lock = FullPathOf(filename);
  640. X    if(!lock) {
  641. X        printf("%ls: Command not found\n",filename);
  642. X        goto usage;
  643. X    }
  644. X    else {
  645. X        /* If file exists, it better be a file and not a directory */
  646. X
  647. X/*DJB*/ /* With my (Dan's) changes, a file that is not found at all
  648. X         * is falsely identified as a directory.  Irritating, but not
  649. X         * fatal.
  650. X         */
  651. X
  652. X        /* Unfortunately, it is difficult to tell if it is an executable
  653. X         * file.  If not executable, we'll still get blown out of the
  654. X         * water, but that is up to the user to do it right!
  655. X         */
  656. X
  657. X        fib =  (struct FileInfoBlock *)
  658. X                AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
  659. X        if(!fib) {
  660. X            UnLock(lock);
  661. X            printf("Ran out of memory!\n");
  662. X            exit(0);
  663. X        }
  664. X        else {
  665. X            success = Examine(lock,fib);
  666. X            if(fib->fib_DirEntryType > 0) {
  667. X/*              printf("%ls is a directory, not a file!\n",filename); */
  668. X/*DJB*/         printf("Cannot open %ls... maybe a directory?\n",filename);
  669. X                goto usage;
  670. X            }
  671. X        }
  672. X        FreeMem(fib, sizeof(struct FileInfoBlock));
  673. X        UnLock(lock);
  674. X    }
  675. X
  676. X    nilfh = Open("NIL:",MODE_NEWFILE); /* will always succeed */
  677. X
  678. X/*TMM*/    /* Mount NULL: device
  679. X              execute "Mount >nil: <nil: null:" command
  680. X              this will ensure that null: is mounted
  681. X              who cares if we try to mount it again ? (KLUDGE)
  682. X           */
  683. X
  684. X    success = Execute( "mount >nil: <nil: null:", nilfh, nilfh );
  685. X
  686. X/*TMM*/ /* Run now redirected to >NULL: <NULL: ( instead of NIL: ) */
  687. X    strcpy( &commandstring[0], "RUN >NULL: <NULL: " );
  688. X    strcat( &commandstring[0], filename);
  689. X
  690. X    /* REMOVE THIS NEXT LINE IF YOU WANT TO INCLUDE REDIRECTION IN
  691. X     * THE COMMAND LINE FOR RUNBACKGROUND.   (The line was installed
  692. X     * to assure that something like "RUNBACKGROUND date ?" would
  693. X     * not crash the system.  "Date ?" is expecting to have an interactive
  694. X     * CLI, and unless it is specifically told to direct its output to nil:
  695. X     * it causes a crash.  If the next line is removed, and you are careful
  696. X     * about putting only NON-interactive commands in the command line,
  697. X     * everything should be ok.  Notice that if you do not specify a
  698. X     * non-interactive file handle (named_disk_file or NIL:) for your
  699. X     * program, it may still prevent the originating CLI from going away
  700. X     * until your program ends.  Also note that specifying two instances
  701. X     * of the same redirection (">somewhere" or "<somewhere") for a
  702. X     * background task crashes.
  703. X     */
  704. X
  705. X/*TMM*/ /* Run now redirected to >NULL: <NULL: ( instead of NIL: ) */
  706. X    strcat( &commandstring[0], " >NULL: <NULL: ");
  707. X
  708. X    argc--;
  709. X
  710. X    while(--argc > 0) {     /* Rebuild parameter string for passing it on */
  711. X        strcat( &commandstring[0], " ");        /* add a blank */
  712. X
  713. X#ifdef AZTEC_C
  714. X        hasSpace = HasASpace(argv[fromparm]);   /* Quoted argument?     */
  715. X        if (hasSpace)                           /* Then quote it again! */
  716. X                strcat( &commandstring[0], "\"");
  717. X#endif
  718. X
  719. X        strcat( &commandstring[0], argv[fromparm++]);
  720. X
  721. X#ifdef AZTEC_C
  722. X        if (hasSpace)
  723. X                strcat( &commandstring[0], "\"");
  724. X#endif
  725. X
  726. X    }
  727. X
  728. X#ifdef DEBUG
  729. X    printf("Execute %s\n", &commandstring[0]);
  730. X#else
  731. X    success = Execute( &commandstring[0] , nilfh, nilfh);
  732. X#endif
  733. X
  734. X        /* The full command passed to Execute now looks like this: */
  735. X
  736. X/*TMM*/ /*  "RUN >NULL: <NULL: FILENAME >NULL: <NULL: PARAMETER(s)" */
  737. X
  738. X
  739. X    if(success) {
  740. X        printf("Started %ls as a background task\n",filename);
  741. X
  742. X        /* Execute, in this case, returns IMMEDIATELY.  The process
  743. X         * that is loading the code that is to be run as a background
  744. X         * process is working to get everything in and started.
  745. X         */
  746. X    }
  747. X    /* Now, to minimize thrashing between tasks, lets put this task to
  748. X     * sleep so that the each task actually gets a chance to load.
  749. X     */
  750. X    Delay(delaywillbe);
  751. X}
  752. X
  753. X
  754. Xstruct FileLock *FullPathOf(filename)
  755. Xchar *filename;
  756. X{
  757. X        struct FileLock *lock;
  758. X        char realname[256], *FindIt();
  759. X
  760. X        strcpy(realname, FindIt(filename));
  761. X        lock = Lock(realname,ACCESS_READ);
  762. X        return(lock);
  763. X}
  764. SHAR_EOF
  765. echo "End of archive 1 (of 1)"
  766. # if you want to concatenate archives, remove anything after this line
  767. exit
  768.